package cn.monkey.chat.server.connect.chat.protocol.http;

import cn.monkey.chat.server.connect.chat.session.UserSessionRepository;
import cn.monkey.chat.server.data.account.UserSession;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * server:
 * bossGroup: 接受链接，创建channel，channel注册到相应workerGroup
 * workerGroup: select/epoll 获取channel里的io状态，read，write channelRead  InboundHandler
 * writeAndFlush data -> outboundHandler
 * <p>
 * <p>
 * ws://ip:port/ws?token=xxxxxxxxxxxxxxxxx
 */
public class HttpUserSessionInboundHandler extends ChannelInboundHandlerAdapter {
    protected final Logger log = LoggerFactory.getLogger(HttpUserSessionInboundHandler.class);
    protected final UserSessionRepository userSessionRepository;

    public HttpUserSessionInboundHandler(UserSessionRepository userSessionRepository) {
        this.userSessionRepository = userSessionRepository;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof FullHttpRequest fullHttpRequest) {
            QueryStringDecoder queryStringDecoder = new QueryStringDecoder(fullHttpRequest.uri());
            Map<String, List<String>> parameters = queryStringDecoder.parameters();
            List<String> token = parameters.get("token");
            if (CollectionUtils.isEmpty(token)) {
                super.channelRead(ctx, msg);
                return;
            }
            String first = token.getFirst();
            CompletableFuture.runAsync(() -> {
                UserSession userSession = this.userSessionRepository.findByToken(first);
                if (userSession == null) {
                    log.error("can not find userSession");
                    ctx.close();
                    return;
                }
                ctx.channel().attr(AttributeKey.valueOf(UserSession.KEY)).set(userSession);
                ctx.pipeline().remove(this);
                // 广播一条onLine // TODO use for test
                ctx.fireChannelRead(msg);
            });
            return;
        }
        super.channelRead(ctx, msg);
    }
}
